package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrPool;
import com.tbit.common.entity.GPS.CarHistory;
import com.tbit.common.utils.GPSUtil;
import com.tbit.uqbike.constant.RedisConstant;
import com.tbit.uqbike.constant.SysConstant;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.MainCar;
import com.tbit.uqbike.object.pojo.TerPosition;
import com.tbit.uqbike.object.pojo.vo.MainCarPageReqVO;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.service.base.CalibrateService;
import com.tbit.uqbike.service.base.HistoryService;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.service.business.MainCarService;
import com.tbit.uqbike.webmanager.util.Assert;
import com.tbit.uqbike.webmanager.util.BeanUtils;
import com.tbit.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 运维车辆轨迹查询
 *
 * @author LMY
 * @create 2021-04-08 10:13
 */
@RestController
@RequestMapping("/mainCarHistory")
public class MainCarHistoryController {

    @Autowired
    private MainCarService mainCarService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private HistoryService historyService;


    /**
     * 根据时间查询单个车辆轨迹
     */
    @RequestMapping("/getByTime")
    public JsonResult getByTime(String machineNO, String startTime, String endTime, Integer mapType) throws Exception {
        Assert.hasLength(startTime, "System.startTime.notNull");
        Assert.hasLength(endTime, "System.endTime.notNull");
        Assert.notNull(machineNO, "Machine.machineNO.notNull");

        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        /* 获取车辆 */
        MainCar mainCarDB = mainCarService.getByMachineNO(machineNO);

        if (mainCarDB == null) {
            throw new BaseException("Machine.notExist");
        }

        String GPSToken = redisService.get(RedisConstant.REDIS_GPS);
        if (GPSToken == null) {
            GPSToken = GPSUtil.login();
            redisService.add(RedisConstant.REDIS_GPS, GPSToken, 59 * 60 * 2);
        }
        //把时间戳字符串转换成年月日时分秒的时间字符串
        startTime = DateTimeUtil.getTimeAllStrByTimeStamp(startTime);
        endTime = DateTimeUtil.getTimeAllStrByTimeStamp(endTime);
        //获取查询的时间分段参数
        List<Map<String, Object>> searchParams = historyService.getSearchParams(machineNO, startTime, endTime,"machineNO",false);
        List<CarHistory> carHistoryList = new ArrayList<>();
        for (Map<String, Object> param : searchParams) {
            /*GPS查车*/
            List<CarHistory> carHistories = GPSUtil.findhistorytrack(GPSToken, machineNO, DateTimeUtil.geTime((Date)param.get("startTime")), DateTimeUtil.geTime((Date)param.get("endTime")));
            /*校准*/
            if (CollUtil.isNotEmpty(carHistories)) {
                calibrateService.calibrateGPSLastPos(carHistories, mapType);
                carHistoryList.addAll(carHistories);
            }
        }
        List<MainCar> mainCars = carHistoryList.stream().map(carHistory -> {
            MainCar mainCar = BeanUtils.copyProperties(mainCarDB, MainCar.class);
            mainCar.fillCarHistory(carHistory);
            return mainCar;
        }).collect(Collectors.toList());
        return JsonResult.ok(mainCars);
    }


    /**
     * 查询所有车辆最后位置
     */
    @RequestMapping("/getPage")
    public JsonResult getPage(MainCarPageReqVO reqVO) throws Exception {
        Assert.notNull(reqVO.getAccountId(), "AccountUser.agentId.notNull");

        /*获取所有车辆id*/
        PageResult<MainCar> page = mainCarService.getPage(reqVO);

        List<MainCar> list = page.getList();
        if (CollUtil.isEmpty(list)) {
            return JsonResult.ok(page);
        }

        String machineNOs = list.stream().map(MainCar::getMachineNO).collect(Collectors.joining(StrPool.COMMA));

        String GPSToken = redisService.get(RedisConstant.REDIS_GPS);
        if (GPSToken == null) {
            GPSToken = GPSUtil.login();
            redisService.add(RedisConstant.REDIS_GPS, GPSToken, 59 * 60 * 2);
        }

        /*GPS查车*/
        List<CarHistory> carHistories = GPSUtil.findlastpos(GPSToken, machineNOs);
        Map<String, CarHistory> carHistoryMap = carHistories.stream().collect(Collectors.toMap(CarHistory::getDevice_no, Function.identity()));
        list.forEach(mainCar -> {
            CarHistory carHistory = carHistoryMap.getOrDefault(mainCar.getMachineNO(), new CarHistory());
            mainCar.fillCarHistory(carHistory);
        });

        if (CollUtil.isNotEmpty(carHistories)) {
            /*校准*/
            calibrateService.calibrateGPSLastPos(carHistories, reqVO.getMapType());
        }
        return JsonResult.ok(page);
    }

    /**
     * 查询单个车辆最后位置
     */
    @RequestMapping("/mainLastPos")
    public JsonResult mainLastPos(String machineNO, Integer mapType) throws Exception {
        Assert.notNull(machineNO, "Machine.machineNO.notNull");

        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        /*获取所有车辆id*/
        MainCar mainCars = mainCarService.getByMachineNO(machineNO);
        if (mainCars == null) {
            throw new BaseException("Machine.notExist");
        }

        String GPSToken = redisService.get(RedisConstant.REDIS_GPS);
        if (GPSToken == null) {
            GPSToken = GPSUtil.login();
            redisService.add(RedisConstant.REDIS_GPS, GPSToken, 59 * 60 * 2);
        }
        /*GPS查车*/
        List<CarHistory> carHistories = GPSUtil.findlastpos(GPSToken, mainCars.getMachineNO());

        /*校准*/
        if (CollUtil.isNotEmpty(carHistories)) {
            List<CarHistory> first = Collections.singletonList(carHistories.get(0));
            calibrateService.calibrateGPSLastPos(first, mapType);
            return JsonResult.ok(carHistories.get(0));
        }

        return JsonResult.ok();
    }

}
